home *** CD-ROM | disk | FTP | other *** search
- /*
- * This file is part of ixemul.library for the Amiga.
- * Copyright (C) 1991, 1992 Markus M. Wild
- * Portions Copyright (C) 1994 Rafael W. Luebbert
- * Portions Copyright (C) 1996 Jeff Shepherd
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
- #define _KERNEL
- #include "ixemul.h"
- #include <stdlib.h>
- #include <string.h>
- #include <pwd.h>
- #include "multiuser.h"
- #include <amitcp/usergroup.h>
-
- static char *
- getUserPasswd(char *name)
- {
- #if 1 /* This gets muFS's password */
- /* Only uncomment this when I figure out how ACrypt works */
- char *retval = NULL;
- char passdir[MAXPATHLEN];
- BPTR passwddir = muGetPasswdDirLock();
-
- if (passwddir) {
- if (NameFromLock(passwddir, passdir, MAXPATHLEN)) {
- if (AddPart(passdir, muPasswd_FileName, MAXPATHLEN)) {
- FILE *fi = (FILE *)syscall(SYS_fopen,passdir,"r");
- char passwdline[1024];
- char username[muUSERNAMESIZE] = {0,};
- char passwd[muPASSWORDSIZE] = {0,};
- int found_it = 0;
-
- if (fi) {
- while (fgets(passwdline,1024,fi)) {
-
- char *sep = strchr(passwdline,'|');
- char *old;
- strncpy(username,passwdline,sep-passwdline);
-
- old = ++sep;
- sep = strchr(old,'|');
- strncpy(passwd,old,sep - old);
-
- if (!strcmp(username,name)) {
- found_it = 1;
- break;
- }
- }
- if (found_it) {
- retval = strdup(passwd);
- }
- fclose(fi);
- }
- }
- }
- UnLock(passwddir);
- }
- if (!retval)
- retval = strdup("*");
- return retval;
- #else
- /* Use the network's password */
- struct passwd *pwd = netcall(NET_getpwnam,name);
- char *retval;
- if (pwd)
- retval = strdup(pwd->pw_passwd);
- else
- retval = strdup("*");
- return retval;
- #endif
- }
-
- /* multiuser doesn't allow a password entry for nobody (uid = 0)
- * I will create one though
- */
- static struct muUserInfo nobody_userinfo = {
- "nobody",
- 0,
- 0,
- "nobody",
- "t:",
- 0,
- (UWORD *)NULL,
- "cli",
- };
-
-
- static struct passwd *
- UserInfo2pw (struct muUserInfo *UI)
- {
- struct passwd *pw = &u.u_passwd;
-
- if (UI == NULL)
- return NULL;
-
- pw->pw_name = UI->UserID;
- pw->pw_dir = UI->HomeDir;
- #if 1
- if (pw->pw_passwd)
- free(pw->pw_passwd);
- pw->pw_passwd = getUserPasswd(pw->pw_name);
- #else
- pw->pw_passwd = "*";
- #endif
- pw->pw_uid = UI->uid;
- pw->pw_gid = UI->gid;
- pw->pw_change = 0;
- pw->pw_class = 0;
- pw->pw_gecos = UI->UserName;
- pw->pw_shell = UI->Shell;
- pw->pw_expire = 0;
-
- return pw;
- }
-
- uid_t
- getuid(void)
- {
- if (muBase)
- return (muGetTaskOwner(NULL) >> 16);
- if (u.u_ixnetbase)
- return netcall(NET_getuid);
- return 0;
- }
-
- uid_t
- geteuid(void)
- {
- if (muBase)
- return getuid();
- if (u.u_ixnetbase)
- return netcall(NET_geteuid);
- return 0;
- }
-
- int
- setuid (uid_t uid)
- {
- int retval = 0;
-
- if (muBase)
- {
- if (getuid() == muROOT_UID)
- {
- struct muUserInfo *UI = muAllocUserInfo();
-
- if (UI) {
- UI->uid = uid;
- UI = muGetUserInfo (UI, muKeyType_uid);
-
- if (muLogin(muT_Task, (ULONG)FindTask(NULL),
- muT_UserID, (ULONG)UI->UserID,
- muT_NoLog, TRUE,
- TAG_DONE)) {
- u.u_setuid++;
- }
- muFreeUserInfo(UI);
- }
- }
- else {
- errno = EPERM;
- retval = -1;
- }
-
- return retval;
- /* I don't think usergroup + muFS need to setuid */
- /* uid = MU2UG(uid); */
- }
-
- if (u.u_ixnetbase)
- return netcall(NET_setuid, uid);
- else
- /* just always succeed... */
- return retval;
- }
-
- int
- seteuid (uid_t uid)
- {
- if (u.u_ixnetbase)
- return netcall(NET_seteuid, uid);
- else
- return setuid(uid);
- }
-
- int
- setreuid (int ruid, int euid)
- {
- if (u.u_ixnetbase)
- return netcall(NET_setreuid, ruid, euid);
- else
- return setuid(euid);
- }
-
- struct passwd *getpwuid (uid_t uid)
- {
- char *name;
- struct passwd *retval;
-
- if (muBase)
- {
- /* active multiuser */
- struct muUserInfo *UI = u.u_UserInfo;
-
- UI->uid = uid;
-
- /*
- * "nobody" can't have a password entry
- * so I will create one
- */
- UI = (uid == muOWNER_NOBODY ? &nobody_userinfo : muGetUserInfo (UI, muKeyType_uid));
-
- return UserInfo2pw (UI); /* handles errors */
- }
-
- if (u.u_ixnetbase)
- return (struct passwd *)netcall(NET_getpwuid, uid);
-
- if ((name = (char *)syscall(SYS_getenv, "USER")))
- retval = (struct passwd *)syscall(SYS_getpwnam, name);
- else
- retval = (struct passwd *)syscall(SYS_getpwnam, "root");
- retval->pw_uid = uid;
- return retval;
- }
-
- struct passwd *getpwnam (const char *name)
- {
- /* this is not quite safe, since this library function could be called
- * in parallel with different names... well, I don't consider this worth
- * doing `right', it's here to be able to link some programs ;-)
- */
- static struct passwd pw = {
- 0, /* pw_name */
- "*", /* pw_passwd */
- 0, /* pw_uid */
- 0, /* pw_gid */
- 0, /* pw_change */
- 0, /* pw_class */
- 0, /* pw_dir */
- 0, /* pw_gecos */
- "/bin/sh", /* pw_shell */
- 0 /* pw_expire */
- };
-
- if (muBase)
- {
- struct muUserInfo *UI = u.u_UserInfo;
-
- /*
- * some validation checks
- */
-
- if (name == NULL)
- return NULL;
-
- if ((muUSERIDSIZE - 1) < strlen (name))
- return NULL;
-
- strcpy (UI->UserID, name);
- UI = muGetUserInfo (UI, muKeyType_UserID);
- /* special case for nobody (uid 0) */
- /* Not sure if this should come before muGetUserInfo()
- * since nobody could have another uid
- */
- if (!UI && !strcmp(name,"nobody"))
- UI = &nobody_userinfo;
-
- return UserInfo2pw (UI); /* handles errors */
- }
-
- if (u.u_ixnetbase)
- return (struct passwd *)netcall(NET_getpwnam, name);
-
- pw.pw_name = (char *)name;
-
- if (!(pw.pw_dir = (char *)syscall(SYS_getenv, "HOME"))) {
- pw.pw_dir = "SYS:";
- }
-
- if (!(pw.pw_gecos = (char *)syscall(SYS_getenv, "REALNAME"))) {
- pw.pw_gecos = "amiga user";
- }
- return &pw;
- }
-
- struct passwd *
- getpwent(void)
- {
- char *name;
-
- if (!muBase && u.u_ixnetbase)
- return (struct passwd *)netcall(NET_getpwent);
- name = getenv("USER");
- if (name)
- return (struct passwd *)syscall(SYS_getpwnam, name);
- return (struct passwd *)syscall(SYS_getpwnam, "root");
- }
-
- int
- setpassent(int stayopen)
- {
- if (u.u_ixnetbase)
- return netcall(NET_setpassent, stayopen);
- return 1;
- }
-
- int
- setpwent(void)
- {
- if (u.u_ixnetbase)
- return netcall(NET_setpwent);
- return 1 ;
- }
-
- void
- endpwent(void)
- {
- if (u.u_ixnetbase)
- netcall(NET_endpwent);
- }
-
- pid_t
- setsid(void)
- {
- if (u.u_ixnetbase)
- return (pid_t)netcall(NET_setsid);
- else {
- errno = EPERM;
- return -1;
- }
- }
-